﻿#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSize>
#include <QCloseEvent>
#include <QSettings>
#include "pilereels.h"
#include "pilerationnels.h"
#include "pileaffichage.h"
#include "pilecomplexes.h"
#include "expression.h"
#include "exception.h"
#include "log.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    //! \brief Implémentation de getInstance pour SINGLETON
    //! on crée une nouvelle instance s'il n'y en avait pas avant et on retourne une référence vers l'instance
    static MainWindow& getInstance();

    //! \brief Implémentation de freeInstance pour SINGLETON
    static void freeInstance();
protected:
    //! \brief Implémentation de SINGLETON
    explicit MainWindow(QWidget *parent = 0);
    MainWindow(const MainWindow&);
    void operator=(const MainWindow&);
    ~MainWindow();

private:

    //! \brief Implémentation de SINGLETON
    static MainWindow * instance;

    //! \brief pointeur utilisé pour générer automatiquement, à partir de mainwindow.ui, l'interface graphique
    Ui::MainWindow *ui;

	//! \brief pointeur sur la pile des réels
    pileReels *pRe;

	//! \brief pointeur sur la pile des rationnels
    pileRationnels *pRa;
	
	//! \brief pointeur sur la pile des complexes
    pileComplexes *pC;
	
	//! \brief pointeur sur la pile d'affichage
    PileAffichage *pA;
	
	//! \brief Taille de la fenêtre pour afficher l'afficheur
    QSize sizeA;
	
	//! \brief Taille de la fenêtre pour afficher l'afficheur et le clavier
    QSize sizeC;
	
	//! \brief Taille de la fenêtre pour afficher l'afficheur, le clavier et la pile
    QSize sizeP;
	
	//! \brief Variable pour stocker l'expression
    expression expr; 
	
    LogSysteme *lS;
    LogMessage *lM;

    //! \brief Pointeur sur la sortie d'affichage des logs
    QTextEdit * console; // pour afficher les messages


    //! \brief Ajoute la chaine s à X
    //!
    //! cette fonction appelle addX(QString s) sur la bonne pile (celle qui est en cours)
    void addX(QString s);
	
	//! \brief Booléen pour connaitre le mode dans angle
	//!
	//!	\return 0 si le mode est en radian
    //! \return 1 si le mode est en degré
    int angleMode;

    //! \brief valeur de convertion pour être dans le mode adéquate
    //!
    //!	\return 1 si le mode est en radian
    //! \return 180/PI si le mode est en degré
    double angle; // 1 : rad , 180/PI : deg

	//! \brief Mode d'utilisation de la calculatrice
	//!
	//!	\return 0 si mode réel
	//! \return 1 si mode rationnel
	//! \return 2 si mode complexe
	//! \return 3 si mode expression
    int mode; 
	
	//! \brief Booléen pour l'affichage du clavier
	//!
	//!	\return 0 si le clavier n'est pas affiché
	//! \return 1 si le clavier est affiché
    int clavier;
	
	//! \brief Booléen pour l'affichage de la pile
	//!
	//!	\return 0 si la pile n'est pas affiché
	//! \return 1 si la pile est affiché
    int pile; 
	
	//! \brief Crée une pile de réels et la charge avec les données du fichier mesOptions.ini
	//!
	//! Passe en mode Réel
    void chargerPileReels();
	
	//! \brief Crée une pile de Complexes et la charge avec les données du fichier mesOptions.ini	
	//!
	//! Passe en mode Complexe
    void chargerPileComplexe();

	//! \brief Crée une pile de Rationnel et la charge avec les données du fichier mesOptions.ini
	//!
	//! Passe en mode Rationnel
    void chargerPileRationnel();
	
	//! \brief Crée une pile d'affichage et la charge avec les données du fichier mesOptions.ini
	//! \bug Probléme d'aafichage avant de rentrer une valeur
	//! \todo Corriger le bug
    void chargerPileAffichage();
	
	//! \brief Rétablie l'interface sauvegardée
	//!
	//! Fonction appellée si présence d'un fichier de sauvegarde
    void affichagePC(int c, int p);
public slots:
    // Menu
	
	//! \brief Fonction pour quitter l'application.
	//!
	//! Sauvegarde le contexte avant de fermer : l'affichage, le mode, la pile utilisé(avec ses valeurs) et l'interface
    void quit_clicked();
    void aClavier_toggled(bool checked);
    void aPile_toggled(bool checked);
    void aReel_toggled(bool checked);
    void aComplexe_toggled(bool checked);
    void aRationnel_toggled(bool checked);
    void aDegre_toggled(bool checked);
    void aRadian_toggled(bool checked);
    void aAnnuler_clicked();
    void aRetablir_clicked();
    void aLog_clicked();
    // Chiffres
    void B0_clicked();
    void B1_clicked();
    void B2_clicked();
    void B3_clicked();
    void B4_clicked();
    void B5_clicked();
    void B6_clicked();
    void B7_clicked();
    void B8_clicked();
    void B9_clicked();
    // Opérateurs
    void BDiv_clicked();
    void BMult_clicked();
    void BSous_clicked();
    void BAdd_clicked();
    // Fonctions
    void BPow_clicked();
    void BMod_clicked();

    void BSqr_clicked();
    void BSqrt_clicked();
    void BCube_clicked();

    void BSin_clicked();
    void BSinH_clicked();
    void BCos_clicked();
    void BCosH_clicked();
    void BTan_clicked();
    void BTanH_clicked();

    void BLn_clicked();
    void BLog_clicked();
    void BExp_clicked();

    void BFact_clicked();

    void BSign_clicked();
    void BInv_clicked();
    // Autre
    void BDot_clicked();
    void BSL_clicked();
    void BMoins_clicked();
    void BApos_clicked();
    void BDollar_clicked();
    void BSpace_clicked();
    void BReturn_clicked();
    void BEnter_clicked();
    void EndCursor();

    // opération sur la pile
    void BSwap_clicked();
    void BSum_clicked();
    void BMean_clicked();
    void BClear_clicked();
    void BDup_clicked();
    void BDrop_clicked();
    void closeEvent(QCloseEvent *event);
};

#endif // MAINWINDOW_H
